﻿using System;
using System.Configuration;
using System.Xml;
using AppUpgrader.Download;
using System.IO;
using System.Windows;
using System.Reflection;

namespace AppUpgrader
{
    public class Upgrader
    {
        public const String KEY_VERSION = "current-version";
        public const String KEY_UPDATE_URL = "update-url";
        public static String VersionConfigFilePath
        {
            get
            {
                // Assembly.GetExecutingAssembly().Location + ".config";
                String path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logistics.exe.config");
                if (!File.Exists(path))
                    throw new Exception("无法找到当前配置文件:" + path);
                return path;
            }
        }

        public String[] GetCurrentVersionAndUpdateURL()
        {
            String[] verAndURL = new String[]{"",""};
            String[] args = Environment.GetCommandLineArgs();
            if (args != null && args.Length > 1)//从启动参数读取,args总是大于1的
            {
                LogUtils.WriteDebug("从启动参数读取版本与更新源");
                for (int i = 0; i < args.Length; i++)
                {
                    if (String.Compare("-v", args[i], true) == 0)//设置了版本
                    {
                        if ((i + 1) < args.Length)
                            verAndURL[0] = args[i + 1];
                    }
                    if (String.Compare("-URL", args[i], true) == 0)//设置了更新地址
                    {
                        if ((i + 1) < args.Length)
                            verAndURL[1] = args[i + 1];
                    }
                }
            }
            else  //从配置文件读取
            {
                String path = VersionConfigFilePath;
                LogUtils.WriteDebug("从文件读取版本与更新源：" + path);

                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(path);
                XmlElement verNode = xDoc.SelectSingleNode(@"//add[@key='" + KEY_VERSION + "']") as XmlElement;
                XmlElement urlNode = xDoc.SelectSingleNode(@"//add[@key='" + KEY_UPDATE_URL + "']") as XmlElement;
                if (verNode != null)
                {
                    verAndURL[0] = verNode.GetAttribute("value");
                }
                if (urlNode != null)
                {
                    verAndURL[1] = urlNode.GetAttribute("value");
                }
            }
            String log = String.Format("当前版本={0},更新源={1}", verAndURL[0], verAndURL[1]);
            LogUtils.WriteDebug(log);
            return verAndURL;
        }

        public static void WriteNewVersion(String version)
        {
            String path = VersionConfigFilePath;
            XmlDocument xDoc = new XmlDocument();
            xDoc.Load(path);
            XmlElement ele = xDoc.SelectSingleNode(@"//add[@key='" + KEY_VERSION + "']") as XmlElement;
            if (ele == null)
            {
                XmlElement appSetting = xDoc.SelectSingleNode(@"//appSettings") as XmlElement;
                ele = xDoc.CreateElement("add");
                appSetting.AppendChild(ele);

                var attrKey = xDoc.CreateAttribute("key");
                attrKey.InnerText = KEY_VERSION;
                ele.Attributes.Append(attrKey);

                var attrVal = xDoc.CreateAttribute("value");
                attrVal.InnerText = "0.0";
                ele.Attributes.Append(attrVal);
            }
            String val = ele.GetAttribute("value");
            if (String.Compare(val, version, true) != 0)
            {
                ele.SetAttribute("value", version);
                xDoc.Save(path);
            }
        }

        public VersionManifest StartCheckVersion()
        {
            String[] verAndURL = GetCurrentVersionAndUpdateURL();
            String currentVersion = verAndURL[0];
            String update_URL = verAndURL[1];

            if (String.IsNullOrWhiteSpace(update_URL))
                throw new ConfigurationErrorsException("can not find value of update_URL");
            if(String.IsNullOrWhiteSpace(currentVersion))
                throw new ConfigurationErrorsException("can not find value of currentVersion");

            double dversion = 0;
            Double.TryParse(currentVersion, out dversion);

            //请求更新文件清单
            LogUtils.WriteDebug("准备请求更新文件清单......");
            String xmlContent = HttpClient.RequestUpdateManifest(update_URL);
            XmlDocument xDoc = new XmlDocument();
            xDoc.LoadXml(xmlContent);

            UpdateManifest manifest = new UpdateManifest(xDoc);

            VersionManifest verManifest = GetUpdateFileLocation(dversion, manifest);
            return verManifest;
        }

        private VersionManifest GetUpdateFileLocation(Double currentVer,UpdateManifest manifest)
        {
            if (currentVer < manifest.BaseManifest.Version)
                return manifest.BaseManifest;
            if (manifest.PatchManifest != null && currentVer < manifest.PatchManifest.Version)
                return manifest.PatchManifest;
            return null;
        }

        public String GetDownloadFilePath(String downloadURL)
        {
            if (String.IsNullOrWhiteSpace(downloadURL))
                throw new ArgumentNullException("下载地址为空" + downloadURL);
            String fileName = System.IO.Path.GetFileName(downloadURL);
            String DownloadDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "_Download");
            if (!System.IO.Directory.Exists(DownloadDir))
            {
                System.IO.Directory.CreateDirectory(DownloadDir);
            }
            String DownloadPath = System.IO.Path.Combine(DownloadDir, fileName);
            if (System.IO.File.Exists(DownloadPath))
            {
                File.Delete(DownloadPath);
            }
            return DownloadPath;
        }

    }
}
